package indi.gtl.superbrain.tools;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import org.apache.http.conn.util.InetAddressUtils;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * Created by admin1 on 15-5-27.
 */
public class NetToolClient {
    private static final String TAG = "NetToolClient";

    public static final String CONNECTION_MSG_CLIENT_SCAN = "scan";
    public static final String CONNECTION_MSG_CLIENT_CONNECT = "connect";

    // 向Handler中传递消息的类型
    // 连接失败
    public static final int HANDLER_MSG_FAIL = 0x11;
    // 搜索到服务器
    public static final int HANDLER_MSG_SCAN = 0x22;
    // 连接服务器成功
    public static final int HANDLER_MSG_CONNECT = 0x33;
    public static final int HANDLER_MSG_SCAN_OVER = 0x44;

    private String locAddress;//存储本机ip，例：本地ip ：192.168.1.
    private Integer haveScanAddNum = 0;

    private Runtime run = Runtime.getRuntime();//获取当前运行环境，来执行ping，相当于windows的cmd

    private static final String ping = "ping -c 1 -w 0.5 " ;//其中 -c 1为发送的次数，-w 表示发送后等待响应的时间

    private OnFindServiceListener mOnFindServiceListener = null;
    private List<String> allFindServiceList;

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case 222:// 服务器消息
                    break;

                case NetToolClient.HANDLER_MSG_SCAN:// 扫描完毕消息
                    String[] info = ((String) msg.obj).split(NetTool.CONNECTION_MSG_SEPARATOR);
                    String ip = info[0];
                    String m = info[1];
                    mOnFindServiceListener.onFindAService(ip, m);
                    break;
                case NetToolClient.HANDLER_MSG_FAIL://扫描失败
                    break;
                case HANDLER_MSG_SCAN_OVER:
                    mOnFindServiceListener.onScanOver(allFindServiceList);
                    break;
            }
        }
    };

    public interface OnFindServiceListener{
        public void onFindAService(String ip, String msg);
        public void onScanOver(List<String> ipList);
    }

    public void setOnFindServiceListener(OnFindServiceListener onFindServiceListener){
        mOnFindServiceListener = onFindServiceListener;
    }

    public NetToolClient(){

    }

    //向serversocket发送消息
    public static String sendMsg(String ip, String msg) {
        String res = null;
        Socket socket = null;

        try {
            socket = new Socket(ip, NetTool.SERVERPORT);

            OutputStream os = socket.getOutputStream();
            os.write((CONNECTION_MSG_CLIENT_SCAN + NetTool.CONNECTION_MSG_SEPARATOR + getLocAddress() + NetTool.CONNECTION_MSG_END).getBytes("utf-8"));
            os.flush();

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            res = bufferedReader.readLine();

            Log.d(TAG, "server 返回信息：" + res);

        } catch (Exception unknownHost) {
            Log.d(TAG, "You are trying to connect to an unknown host!" + ip);
        } finally {
            // 4: Closing connection
            try {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
        return res;
    }

    /**
     * 扫描局域网内ip，找到对应服务器
     */
    public void scan(){
        allFindServiceList = new ArrayList<String>();
        haveScanAddNum = 0;
        locAddress = getLocAddrIndex();//获取本地ip前缀

        if(locAddress.equals("")){
            Message.obtain(mHandler, HANDLER_MSG_FAIL).sendToTarget();
            return ;
        }

        for ( int i = 100; i < 103; i++) {//创建256个线程分别去ping
            new Thread(new ConnectRunnable(i)).start();
        }
    }

    // 多线程搜索的类
    class ConnectRunnable implements Runnable {
        int j;

        ConnectRunnable(int j){
            this.j = j;
        }

        @Override
        public void run() {
            String p = ping + locAddress + j;

            String current_ip = locAddress + j;
            Log.d(TAG, "扫描ip:" + current_ip);
            Log.d(TAG, "连接" + current_ip);
            // 向服务器发送验证信息
            String msg = sendMsg(current_ip, CONNECTION_MSG_CLIENT_SCAN);
            Log.d(TAG, "连接msg: " + msg + "    :     " + current_ip);
            //如果验证通过...
            if (msg != null){
                Log.d(TAG, "服务器IP：" + msg);
                synchronized (allFindServiceList) {
                    allFindServiceList.add(msg);
                }
                String[] m = msg.split(NetTool.CONNECTION_MSG_SEPARATOR);
                Message.obtain(mHandler, HANDLER_MSG_SCAN, m[1] + NetTool.CONNECTION_MSG_SEPARATOR + m[2]).sendToTarget();//返回扫描完毕消息
            }

            synchronized (haveScanAddNum) {
                haveScanAddNum++;
            }
        }
    }

    //连接服务器
    public static NetTool connectService(String ip){
        NetTool netTool = null;
        Log.d(TAG, "连接服务器：" + ip);

        Socket socket = null;
        String msg = null;

        try {
            socket = new Socket(ip, NetTool.SERVERPORT);
            Log.d(TAG, "向服务器发送：" + ip);
            OutputStream os = socket.getOutputStream();
            os.write((CONNECTION_MSG_CLIENT_CONNECT + NetTool.CONNECTION_MSG_SEPARATOR + getLocAddress() + NetTool.CONNECTION_MSG_END).getBytes("utf-8"));
            os.flush();

            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            msg = bufferedReader.readLine();
            // Message.obtain(mHandler, HANDLER_MSG_SCAN, res).sendToTarget();//发送服务器返回消息
            if(msg != null){
                String[] info = msg.split(NetTool.CONNECTION_MSG_SEPARATOR);
                if(info[0].equals(NetToolService.CONNECTION_MSG_SERVICE_CONNECT)){
                    netTool = NetTool.createNetTool(ip, socket);
                    // Message.obtain(mHandler, HANDLER_MSG_CONNECT, info[1]).sendToTarget();//返回扫描完毕消息
                }
            }else{
                socket.close();
            }
        } catch (Exception unknownHost) {
            Log.d(TAG, "You are trying to connect to an unknown host!" + ip);
        }

        return netTool;
    }

    public static void connectServiceAndSetListener(final String ip, final NetTool.OnReceiveMessageListener onReceiveMessageListener) {
        new Thread() {
            @Override
            public void run() {
                NetTool mNetTool = NetToolClient.connectService(ip);
                if (mNetTool != null) {
                    mNetTool.setOnReceiveMessageListener(onReceiveMessageListener);
                }
            }
        }.start();
    }

    //获取本地ip地址
    public static String getLocAddress(){
        String ipaddress = "";

        try {
            Enumeration en = NetworkInterface.getNetworkInterfaces();
            // 遍历所用的网络接口
            while (en.hasMoreElements()) {
                NetworkInterface networks = (NetworkInterface) en.nextElement();
                // 得到每一个网络接口绑定的所有ip
                Enumeration address = networks.getInetAddresses();
                // 遍历每一个接口绑定的所有ip
                while (address.hasMoreElements()) {
                    InetAddress ip = (InetAddress) address.nextElement();
                    if (!ip.isLoopbackAddress()
                            && InetAddressUtils.isIPv4Address(ip.getHostAddress())) {
                        ipaddress = ip.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            Log.e("", "获取本地ip地址失败");
            e.printStackTrace();
        }

        Log.d(TAG, "本机IP:" + ipaddress);

        return ipaddress;

    }

    //获取IP前缀
    public String getLocAddrIndex(){

        String str = getLocAddress();

        if(!str.equals("")){
            return str.substring(0,str.lastIndexOf(".")+1);
        }

        return null;
    }

    //获取本机设备名称
    public String getLocDeviceName() {

        return android.os.Build.MODEL;

    }


}
